<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Three Color Gradient Shader</title>
    <style>
        body { margin: 0; }
        canvas { display: block; }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const gl = canvas.getContext('webgl');

        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        gl.viewport(0, 0, canvas.width, canvas.height);

        const vertexShaderSource = `
            attribute vec4 a_position;
            varying vec2 v_uv;
            void main() {
                v_uv = a_position.xy * 0.5 + 0.5;
                gl_Position = a_position;
            }
        `;

        const fragmentShaderSource = `
            precision mediump float;
            varying vec2 v_uv;
            uniform vec4 u_color1;
            uniform vec4 u_color2;
            uniform vec4 u_color3;

            void main() {
                float t = v_uv.x;
                vec4 color1To2 = mix(u_color1, u_color2, clamp(t * 2.0, 0.0, 1.0));
                vec4 color2To3 = mix(u_color2, u_color3, clamp((t - 0.5) * 2.0, 0.0, 1.0));
                float mid = step(0.5, t);
                gl_FragColor = mix(color1To2, color2To3, mid);
            }
        `;

        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                console.error('Error compiling shader:', gl.getShaderInfoLog(shader));
                gl.deleteShader(shader);
                return null;
            }
            return shader;
        }

        function createProgram(gl, vertexShader, fragmentShader) {
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                console.error('Error linking program:', gl.getProgramInfoLog(program));
                gl.deleteProgram(program);
                return null;
            }
            return program;
        }

        const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
        const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
        const program = createProgram(gl, vertexShader, fragmentShader);

        const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
        const color1UniformLocation = gl.getUniformLocation(program, 'u_color1');
        const color2UniformLocation = gl.getUniformLocation(program, 'u_color2');
        const color3UniformLocation = gl.getUniformLocation(program, 'u_color3');

        const positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        const positions = [
            -1, -1,
             1, -1,
            -1,  1,
            -1,  1,
             1, -1,
             1,  1,
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);

        gl.useProgram(program);

        gl.enableVertexAttribArray(positionAttributeLocation);
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

        gl.uniform4f(color1UniformLocation, 1.0, 0.0, 0.0, 1.0); // Red
        gl.uniform4f(color2UniformLocation, 0.0, 1.0, 0.0, 1.0); // Green
        gl.uniform4f(color3UniformLocation, 0.0, 0.0, 1.0, 1.0); // Blue

        gl.drawArrays(gl.TRIANGLES, 0, 6);
    </script>
</body>
</html>
